package com.keyue.isolate.aspect;


import com.keyue.common.constant.Constant;
import com.keyue.common.exception.BusinessException;
import com.keyue.common.utils.JsonUtil;
import com.keyue.common.utils.UserUtils;
import com.keyue.domain.DataPermissionItemVO;
import com.keyue.domain.DataPermissionRedisVO;
import com.keyue.isolate.annotation.DataIsolate;
import com.keyue.isolate.annotation.IgnoreDataIsolate;
import com.keyue.isolate.context.DataIsolateContextHolder;
import com.keyue.isolate.context.DataIsolateValue;
import com.keyue.isolate.enums.DataPermissionModelEnum;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Component
@Aspect
@Slf4j
public class DataIsolateAspect {

    @Resource
    private UserUtils userUtils;

    @Around("@annotation(ignoreDataIsolate)")
    public Object ignoreDataIsolateAnnotation(ProceedingJoinPoint joinPoint, IgnoreDataIsolate ignoreDataIsolate) throws Throwable {
        try {
            if (ignoreDataIsolate.ignoreBefore()) {
                DataIsolateContextHolder.markIgnoreBefore();
            }

            if (ignoreDataIsolate.ignoreAfter()) {
                DataIsolateContextHolder.markIgnoreAfter();
            }

            return joinPoint.proceed();
        } finally {
            DataIsolateContextHolder.unMarkIgnore();
        }
    }

    @Around("@annotation(dataIsolate)")
    public Object setIsolateConfig(ProceedingJoinPoint joinPoint, DataIsolate dataIsolate) throws Throwable {
        if (!userUtils.isNewDataPermissionSwitch()) {
            //数据权限开关未打开 可以查看全部
            return joinPoint.proceed();
        }

        if (DataIsolateContextHolder.needIgnoreAfter()) {

            return joinPoint.proceed();
        }
        
        List<DataPermissionRedisVO> dataPermissionRedisVOS = userUtils.getCurrentUserInfo().getDataPermissionRedisVOS();
        if (CollectionUtils.isEmpty(dataPermissionRedisVOS)) {
            throw new BusinessException("未配置数据权限,无法查看数据");
            //没有配置数据权限 可以查看全部
//            return joinPoint.proceed();
        }
        
        List<String> modelTypes = Arrays.stream(dataIsolate.models()).map(DataPermissionModelEnum::getModelType).collect(Collectors.toList());;
        List<DataPermissionItemVO> modelDataPermissionItemVOs = dataPermissionRedisVOS.stream()
                .filter(x -> {
                    List<String> dataPermissionModelTypes = Arrays.asList(x.getModelType().split(Constant.COMMA_CHARACTER));
                    return modelTypes.stream().anyMatch(dataPermissionModelTypes::contains);
                })
                .map(x -> JsonUtil.jsonToEntity(x.getDataPermissionItemVOJson(), DataPermissionItemVO.class))
                .filter(Objects::nonNull)
                //将非当前模块的字段置空 不参与后面的数据隔离
                .peek(x -> x.removeNoNeedFieldValue(modelTypes))
                .collect(Collectors.toList());;
        if (CollectionUtils.isEmpty(modelDataPermissionItemVOs)) {
            //无当前模块的数据隔离配置
            throw new BusinessException("未配置数据权限,无法查看数据");
//            return joinPoint.proceed();
        }

        List<DataIsolateValue> dataIsolateValues = new ArrayList<>(modelDataPermissionItemVOs.size());

        for (DataPermissionItemVO modelDataPermissionItemVO : modelDataPermissionItemVOs) {
            DataIsolateValue dataIsolateValue = new DataIsolateValue();
            dataIsolateValue.setCarrierCodes(modelDataPermissionItemVO.getCarrierCodes());
            dataIsolateValue.setCompanyCodes(modelDataPermissionItemVO.getCompanyCodes());
            dataIsolateValue.setContractBodyCodes(modelDataPermissionItemVO.getContractBodyCodes());
            dataIsolateValue.setCustomerCodes(modelDataPermissionItemVO.getCustomerCodes());
            dataIsolateValue.setSubTransportTypeCodes(modelDataPermissionItemVO.getSubTransportTypeCodes());
            dataIsolateValue.setSourcePlatformCodes(modelDataPermissionItemVO.getSourcePlatformCodes());
            dataIsolateValue.setWarehouseCodes(modelDataPermissionItemVO.getWarehouseCodes());
            dataIsolateValue.setTransportTypeCodes(modelDataPermissionItemVO.getTransportTypeCodes());
            dataIsolateValue.setFromCityCodes(modelDataPermissionItemVO.getFromCityCodes());
            dataIsolateValues.add(dataIsolateValue);
        }

        try {
            DataIsolateContextHolder.setContextValue(dataIsolateValues);
            return joinPoint.proceed();
        } finally {
            DataIsolateContextHolder.clear();
        }
    }


}
